using Cysharp.Threading.Tasks;
using IQIGame.Onigao.Framework;
using IQIGame.Onigao.Game;
using RecastUnity;
using System;
using UnityEngine;

namespace IQIGame.Onigao.GamePlay
{
    public class LevelPlayNavigationCtrl : TNavigationController
    {
        public LevelPlayRegionController regionCtrl => parent as LevelPlayRegionController;
        public IntPtr navMeshScene => _navMeshScene;

        protected override bool isActiveRecastObstacle => false;

        protected override void OnModuleGameplayInit()
        {
            this.regionCtrl.sceneCtrl.AddFirstPreloadAfterScene(LoadRegionNavigation);
        }

        protected override void OnSceneLoaded()
        {

        }

        private async UniTask LoadRegionNavigation()
        {
            if (_navMeshScene != IntPtr.Zero)
            {
                RecastDll.RecastClear(_navMeshScene);
            }

            //缓存里没有就加载
            //该缓存是本地模式专用缓存，这里相当于针对本地模式做一个优化
            var levelPlayCtrl = regionCtrl.levelPlayCtrl;
            int regionCid = regionCtrl.cfgRegionPack.cfgRegionInstance.Id;
            if (!levelPlayCtrl.isLocal || !levelPlayCtrl.navFilesForLocal.TryGetValue(regionCid, out byte[] bytes))
            {
                string navMeshName = regionCtrl.cfgRegionPack.cfgScene.NavMesh;
                var resloader = ResLoader.Create();
                var path = PathConstant.GetNavMeshCfg(navMeshName);
                var text = await resloader.LoadABAssetAwait<TextAsset>(path);
                if (text == null)
                {
                    LogGame.LogError("Load NavMesh failed:" + path);
                }
                bytes = text.bytes;
                resloader.Put2Pool();
            }

            _navMeshScene = RecastDll.RecastLoad(RecastDllID.LevelView, bytes, bytes.Length, true);

            if (_navMeshScene == IntPtr.Zero)
            {
                LogGame.LogError("Init NavMesh failed." + PathConstant.GetNavMeshCfg(regionCtrl.cfgRegionPack.cfgScene.NavMesh));
                return;
            }

            //获取边界
            if (RecastUtility.RecastTryGetBounds(_navMeshScene, out var b))
            {
                bounds = b;
                var min = bounds.min;
                var size = bounds.size;
                boundsRect = new Rect(min.x, min.z, size.x, size.z);
            }
            else
            {
                LogGame.LogError("NavMesh get bounds failed");
            }

#if UNITY_EDITOR
            GamePlayDebugUtil.RefreshNavMeshPreview(GameplayAreaType.Level, _navMeshScene);
#endif
        }

        protected override void OnDispose()
        {
            base.OnDispose();
        }
    }
}
